﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace kompot_wtf
{
    public class FullScreenEffects
    {
        static Effect lightEffect;
        static Effect radarEffect;
        static Effect deathEffect;
        static Effect enemyRadarEffect;

        static VertexPositionTexture[] vertices = new VertexPositionTexture[4];
        static short[] indices = new short[6];

        static Vector2 ScreenSize;

        public static void Load(Vector2 screenSize)
        {
            lightEffect = WTF.ContentMgr.Load<Effect>("Shaders//Light");
            radarEffect = WTF.ContentMgr.Load<Effect>("Shaders//Radar");
            deathEffect = WTF.ContentMgr.Load<Effect>("Shaders//Death");
            enemyRadarEffect = WTF.ContentMgr.Load<Effect>("Shaders//EnemyRadar");

            indices[0] = 0;
            indices[1] = 1;
            indices[2] = 3;
            indices[3] = 0;
            indices[4] = 3;
            indices[5] = 2;

            vertices[0] = new VertexPositionTexture(new Vector3(-1, 1, 0), Vector2.Zero);
            vertices[1] = new VertexPositionTexture(new Vector3(1, 1, 0), Vector2.Zero);
            vertices[2] = new VertexPositionTexture(new Vector3(-1, -1, 0), Vector2.Zero);
            vertices[3] = new VertexPositionTexture(new Vector3(1, -1, 0), Vector2.Zero);

            ScreenSize = screenSize;
        }

        static bool change;
        static float changeTime = 1.0f;
        static float timeFromChange = changeTime;

        public static void Update(float dt, Player player)
        {
            timeFromChange += dt;
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
                if (timeFromChange > changeTime)
                {
                    change = !change;
                    timeFromChange = 0.0f;
                }

            List<EnemyToDraw> toRemove = new List<EnemyToDraw>();
            foreach (EnemyToDraw etd in enemiesToDraw)
            {
                etd.strength -= dt * EnemyToDraw.strengthDecSpeed;
                if (etd.strength <= 0)
                    toRemove.Add(etd);
            }

            foreach (EnemyToDraw etd in toRemove)
            {
                enemiesToDraw.Remove(etd);
            }
        }

        public static void DrawLight(GraphicsDevice device, float radius)
        {
            
            DepthStencilState ds = new DepthStencilState();
            ds.DepthBufferEnable = false;
            device.DepthStencilState = ds;
            device.BlendState = BlendState.AlphaBlend;

            lightEffect.Parameters["screenSize"].SetValue(ScreenSize);
            lightEffect.Parameters["change"].SetValue(change);
            lightEffect.Parameters["radius"].SetValue(radius);

            foreach (EffectPass pass in lightEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3, VertexPositionTexture.VertexDeclaration);
            }
        }

        public static void DrawRadar(GraphicsDevice device, Player player)
        {
            if (GameState.state == GameState.State.THIEF || GameState.state == GameState.State.PLAYER_ESCAPE
                || GameState.state == GameState.State.ZOMBIES_ESCAPE)
            {

                DepthStencilState ds = new DepthStencilState();
                ds.DepthBufferEnable = false;
                device.DepthStencilState = ds;
                device.BlendState = BlendState.AlphaBlend;

                radarEffect.Parameters["screenSize"].SetValue(ScreenSize);
                radarEffect.Parameters["radius"].SetValue(player.CurrentRadarRadius);
                radarEffect.Parameters["maxRadius"].SetValue(player.MAX_RADAR_RADIUS);

                foreach (EffectPass pass in radarEffect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3, VertexPositionTexture.VertexDeclaration);
                }
            }
        }

        public static void DrawDeath(GraphicsDevice device)
        {

            DepthStencilState ds = new DepthStencilState();
            ds.DepthBufferEnable = false;
            device.DepthStencilState = ds;
            device.BlendState = BlendState.AlphaBlend;

            deathEffect.Parameters["screenSize"].SetValue(ScreenSize);

            foreach (EffectPass pass in deathEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3, VertexPositionTexture.VertexDeclaration);
            }
        }

        class EnemyToDraw
        {
            public Vector2 position;
            public float strength;

            public const float strengthDecSpeed = 1.0f;
        }
        static List<EnemyToDraw> enemiesToDraw = new List<EnemyToDraw>();

        public static void AddEnemyRadar(Vector2 position)
        {
            EnemyToDraw newE = new EnemyToDraw() ;
            newE.position = position;
            newE.strength = 1.0f;
            enemiesToDraw.Add(newE);
        }

        public static void DrawEnemyRadars(GraphicsDevice device)
        {
            foreach (EnemyToDraw etd in enemiesToDraw)
            {
                DepthStencilState ds = new DepthStencilState();
                ds.DepthBufferEnable = false;
                device.DepthStencilState = ds;
                device.BlendState = BlendState.AlphaBlend;

                VertexPositionTexture[] verticeLocal = new VertexPositionTexture[4];

                float offsetX = 0.075f;
                float offsetY = 0.1f;

                Vector2 position = GameObject.TransformWorldPosToScreenPos(etd.position);
                position.Y = ScreenSize.Y-position.Y;

                Vector2 middle = position / new Vector2(WTF.ScreenWidth / 2, WTF.ScreenHeight / 2) - new Vector2(1, 1);

                enemyRadarEffect.Parameters["middle"].SetValue(position);
                enemyRadarEffect.Parameters["screenSize"].SetValue(ScreenSize);
                enemyRadarEffect.Parameters["strength"].SetValue(etd.strength);

                verticeLocal[0] = new VertexPositionTexture(new Vector3(middle.X - offsetX, middle.Y + offsetY, 0), Vector2.Zero);
                verticeLocal[1] = new VertexPositionTexture(new Vector3(middle.X + offsetX, middle.Y + offsetY, 0), Vector2.Zero);
                verticeLocal[2] = new VertexPositionTexture(new Vector3(middle.X - offsetX, middle.Y - offsetY, 0), Vector2.Zero);
                verticeLocal[3] = new VertexPositionTexture(new Vector3(middle.X + offsetX, middle.Y - offsetY, 0), Vector2.Zero);

                foreach (EffectPass pass in enemyRadarEffect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, verticeLocal, 0, verticeLocal.Length, indices, 0, indices.Length / 3, VertexPositionTexture.VertexDeclaration);
                }
            }
        }
    }
}
